(function($) {
	const axios = require('axios');
	const Qs = require('qs');

	// 默认请求实例
	const requestInstance = axios.create({
		responseType: 'json',
		withCredentials: true,
		timeout: 30000,
		header: {
			'Content-Type': 'application/json',
		},
		paramsSerializer: function(params) {
			return Qs.stringify(params, {arrayFormat: 'brackets'});
		},
	});

	// fix custom config attr
	requestInstance.interceptors.request.use(function(config) {
		const originalConfig = config.url.$;
		config.url = config.url.url;
		Object.keys(originalConfig).forEach(key => {
			if (config[key] === undefined) {
				config[key] = originalConfig[key];
			}
		});

		return config;
	});

	/**
	 * 网络请求
	 * @param {*} options
	 * @return {Promise}
	 */
	function request(options) {
		options = Object.assign({}, options);

		// fix custom config attr
		options.url = {
			url: options.url,
			$: options
		};

		options.method = options.method ? options.method.toLowerCase() : 'get';
		options.headers = options.headers || {};

		if (['get', 'delete', 'options'].indexOf(options.method) !== -1) {
			if (options.data && !options.params) {
				options.params = options.data;
				delete options.data;
			}
		} else {
			// options.headers['Content-Type'] = 'application/json';
			// options.headers['Content-Type'] = 'text/plain';
			// options.headers['Content-Type'] = 'application/x-www-form-urlencoded';
			const contentType = options.headers['Content-Type'] || request.defaults.headers['Content-Type'];
			if ('application/x-www-form-urlencoded' === contentType) {
				if (options.data) options.data = Qs.stringify(options.data, {
					encodeValuesOnly: true
				});
			}
		}

		return requestInstance.request(options);
	}

	['get', 'post', 'delete', 'put'].forEach(name => {
		/**
		 * 快捷请求
		 * @param {string} url
		 * @param {*} data
		 * @param {*} options
		 * @return {Promise}
		 */
		request[name] = function(url, data, options = {}) {
			return request(Object.assign({url, data, method: name}, options));
		};
	});


	/**
	 * @type {AxiosRequestConfig}
	 */
	request.defaults = requestInstance.defaults;

	/**
	 * 全部请求
	 * @param {Promise[]} requests
	 * @return {Promise}
	 */
	request.all = (requests) => {
		return axios.all(requests);
	};

	/**
	 * 创建一个新实例
	 * @param {*} options
	 * @return {*|AxiosPromise}
	 */
	request.create = function(options) {
		return axios(options);
	};

	/**
	 * 添加请求拦截器
	 * @param {function} [fulfilled]
	 * @param {function} [rejected]
	 * @return {number}
	 */
	request.addRequestInterceptor = (fulfilled, rejected) => {
		const interceptors = requestInstance.interceptors.request;
		interceptors.handlers.unshift({
			fulfilled: fulfilled,
			rejected: rejected
		});
		return interceptors.handlers.length - 1;
	};

	/**
	 * 移除请求拦截器
	 * @param {number} interceptor
	 */
	request.removeRequestInterceptor = (interceptor) => {
		requestInstance.interceptors.request.eject(interceptor);
	};


	/**
	 * 添加响应拦截器
	 * @param {function} [onFulfilled]
	 * @param {function} [onRejected]
	 * @return {number}
	 */
	request.addResponseInterceptor = (onFulfilled, onRejected) => {
		return requestInstance.interceptors.response.use(onFulfilled, onRejected);
	};

	/**
	 * 移除响应拦截器
	 * @param {number} interceptor
	 */
	request.removeResponseInterceptor = (interceptor) => {
		requestInstance.interceptors.response.eject(interceptor);
	};

	$.define('request', request);
})($);

